package com.lagou.rpc.consumer.proxy;

import com.alibaba.fastjson.JSON;
import com.lagou.rpc.common.RpcRequest;
import com.lagou.rpc.common.RpcResponse;
import com.lagou.rpc.consumer.client.RpcClient;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.UUID;
import java.util.concurrent.ExecutionException;

/**
 *  客户端代理类：创建代理对象
 *  1.封装request请求对象
 *  2.创建RpcClient对象
 *  3.发送消息
 *  4.返回结果
 */
public class RpcClientProxy {

    public static Object createProxy(Class serviceClass, RpcClient rpcClient){
        // 使用jdk动态代理
        return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
                new Class[]{serviceClass}, new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        // 1.封装request请求对象
                        RpcRequest rpcRequest  = new RpcRequest();
                        rpcRequest.setRequestId(UUID.randomUUID().toString()); // 使用UUID来生成requestID
                        rpcRequest.setClassName(method.getDeclaringClass().getName());
                        rpcRequest.setMethodName(method.getName());
                        rpcRequest.setParameterTypes(method.getParameterTypes());
                        rpcRequest.setParameters(args);
                        // 2.创建RpcClient对象
                        RpcClient rpcClient = new RpcClient("127.0.0.1",8899);
                        try {
                            // 3.发送消息，返回值是  服务端发送过来的消息
                            Object responseMessage = rpcClient.send(JSON.toJSONString(rpcRequest));
                            //把上一步 服务端发送过来的消息  得到响应对象
                            RpcResponse rpcResponse = JSON.parseObject(responseMessage.toString(), RpcResponse.class);
                            if (rpcResponse.getError() != null){ // 判断响应对象有没有错误信息
                                throw new RuntimeException(rpcResponse.getError());
                            }
                            // 4.返回结果
                            Object result = rpcResponse.getResult();
                            return JSON.parseObject(result.toString(),method.getReturnType());
                        } catch (ExecutionException e) {
                           throw e;
                        }finally {
                            rpcClient.close();
                        }
                    }
                });
    }

}
